#!/bin/env python3
# -*- coding:utf-8 -*-
"""
    数据库
    # flask --app mysqls db init
    flask --app mysqls db migrate
    # 如果报错 flask  --app mysqls db revision --rev-id ccf3328d8200
    flask --app mysqls db upgrade

"""
import sys,os
from pdb import set_trace as strace
from traceback  import format_exc as dumpstack
from datetime import datetime
from collections import OrderedDict
import logging

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from sqlalchemy import text

from app.flaskapp import webapp as app

db = SQLAlchemy(app)

class ModelUuids(db.Model):
    # 模板信息
    __tablename__ = 'uuids'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer, primary_key=True,  index=True)
    info        = db.Column(db.Text,        comment="信息载体", nullable=False,   default="")
    uuid        = db.Column(db.String( 32), comment="编号",     nullable=False,   default="")
    ip          = db.Column(db.String( 39), comment="IP地址",   nullable=True,    default="")
    agent       = db.Column(db.Text,        comment="客户端",   nullable=True,    default="")

    status      = db.Column(db.Boolean,     comment="是否启用", nullable=False, server_default=text('true'))
    create_time = db.Column(db.DateTime,    default=datetime.now, nullable=False, comment="创建时间")

class ModelShellTmpl(db.Model):
    # 模板信息
    __tablename__ = 'shelltmpls'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer, primary_key=True,  index=True)
    desc        = db.Column(db.String(255), comment="备注", nullable=False,   default="")
    code        = db.Column(db.String( 32), comment="编号", nullable=False,   default="")
    owner       = db.Column(db.String( 32), comment="属主", nullable=False,   default="")
    tmpl        = db.Column(db.Text,        comment="内容", nullable=False,   default="")

    status      = db.Column(db.Boolean,     comment="是否启用", nullable=False, server_default=text('true'))
    removed     = db.Column(db.Boolean,     comment="删除标记", nullable=False, server_default=text('false'))
    create_time = db.Column(db.DateTime,    default=datetime.now, nullable=False, comment="创建时间")

class ModelType(db.Model):
    __tablename__ = 'types'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer, primary_key=True, index=True)
    name        = db.Column(db.String(255), comment="类型名", nullable=False,  unique=True)
    detail      = db.Column(db.Text,        comment="备注",   nullable=False,    default="")

    status      = db.Column(db.Boolean,     comment="是否启用", nullable=False, server_default=text('true'))
    removed     = db.Column(db.Boolean,     comment="删除标记", nullable=False, server_default=text('false'))
    create_time = db.Column(db.DateTime,    default=datetime.now, nullable=False, comment="创建时间")

class ModelUsers(db.Model):
    __tablename__ = 'users'
    __table_args__ = (
            db.UniqueConstraint('uuid', 'types'),
        )

    id          = db.Column(db.Integer,     nullable=False, autoincrement=True, unique=True)
    uuid        = db.Column(db.String(255), comment="身份UUID", nullable=False, primary_key=True)
    money       = db.Column(db.BigInteger,  comment="余量", nullable=False)
    name        = db.Column(db.String(255), comment="姓名", nullable=False)
    detail      = db.Column(db.Text,        comment="备注", nullable=False)
    types       = db.Column(db.Integer, db.ForeignKey("types.id"), comment="账户类型", nullable=False, primary_key=True)

    status      = db.Column(db.Boolean,     comment="记录有/失效", nullable=False, server_default=text('true'))
    removed     = db.Column(db.Boolean,     comment="删除标记", nullable=False, server_default=text('false'))
    create_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间", nullable=False)

class ModelUtxo(db.Model):
    __tablename__ = 'utxo'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer, primary_key=True, index=True)
    money       = db.Column(db.BigInteger,  comment="变化量，支持正负" , nullable=False)
    detail      = db.Column(db.Text,        comment="备注" , nullable=False)
    billingtype = db.Column(db.Boolean,     comment="是否入账" , nullable=False)

    uid         = db.Column(db.Integer,     comment="账户ID(非UUID)" , nullable=False)
    uuid        = db.Column(db.String(255), comment="身份UUID", nullable=False)
    types       = db.Column(db.Integer,     comment="账户类型" , nullable=False)

    status      = db.Column(db.Boolean,     comment="状态标记", nullable=False, server_default=text('true'))
    removed     = db.Column(db.Boolean,     comment="删除标记", nullable=False, server_default=text('false'))
    create_time = db.Column(db.DateTime,    default=datetime.now, nullable=False, comment="创建时间")

class ModelMoneyDay(db.Model):
    __tablename__ = 'days'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer,     primary_key=True, index=True)
    money       = db.Column(db.BigInteger,  comment="变化量", nullable=False)

    day         = db.Column(db.DateTime,    comment="日期", nullable=False)
    uid         = db.Column(db.Integer,     comment="账户ID", nullable=False)
    uuid        = db.Column(db.String(255), comment="身份UUID", nullable=False)
    types       = db.Column(db.Integer,     comment="账户类型", nullable=False)

    # status      = db.Column(db.Boolean,     comment="状态标记", nullable=False, server_default=text('true'))
    # removed     = db.Column(db.Boolean,     comment="删除标记", nullable=False, server_default=text('false'))
    create_time = db.Column(db.DateTime,    default=datetime.now, comment="创建时间")

class ModelMoneyMon(db.Model):
    __tablename__ = 'month'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer,     primary_key=True, index=True)
    money       = db.Column(db.BigInteger,  comment="变化量", nullable=False)

    day         = db.Column(db.DateTime,    comment="日期", nullable=False)
    uid         = db.Column(db.Integer,     comment="账户ID", nullable=False)
    uuid        = db.Column(db.String(255), comment="身份UUID", nullable=False)
    types       = db.Column(db.Integer,     comment="账户类型", nullable=False)

    # status      = db.Column(db.Boolean,     comment="状态标记", nullable=False, server_default=text('true'))
    # removed     = db.Column(db.Boolean,     comment="删除标记", nullable=False, server_default=text('false'))
    create_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间", nullable=False)

class ModelCards(db.Model):
    __tablename__ = 'cards'
    __table_args__ = {'extend_existing': True}

    id = db.Column(db.Integer, primary_key=True, index=True)

    uid   = db.Column(db.Integer, comment="第几局")
    plays = db.Column(db.Integer, comment="几个玩家")

    c1 = db.Column(db.Integer, nullable=False, comment="第一张公牌")
    c2 = db.Column(db.Integer, nullable=False, comment="第二张公牌")
    c3 = db.Column(db.Integer, nullable=False, comment="第三张公牌")
    c4 = db.Column(db.Integer, nullable=False, comment="第四张公牌")
    c5 = db.Column(db.Integer, nullable=False, comment="第五张公牌")

    p11 = db.Column(db.Integer, nullable=True, comment="玩家一的手牌1")
    p12 = db.Column(db.Integer, nullable=True, comment="玩家一的手牌2")

    p21 = db.Column(db.Integer, nullable=True, comment="玩家二的手牌1")
    p22 = db.Column(db.Integer, nullable=True, comment="玩家二的手牌2")

    p31 = db.Column(db.Integer, nullable=True, comment="玩家3的手牌1")
    p32 = db.Column(db.Integer, nullable=True, comment="玩家3的手牌2")

    p41 = db.Column(db.Integer, nullable=True, comment="玩家4的手牌1")
    p42 = db.Column(db.Integer, nullable=True, comment="玩家4的手牌2")

    p51 = db.Column(db.Integer, nullable=True, comment="玩家5的手牌1")
    p52 = db.Column(db.Integer, nullable=True, comment="玩家5的手牌2")

    p61 = db.Column(db.Integer, nullable=True, comment="玩家6的手牌1")
    p62 = db.Column(db.Integer, nullable=True, comment="玩家6的手牌2")

    p71 = db.Column(db.Integer, nullable=True, comment="玩家7的手牌1")
    p72 = db.Column(db.Integer, nullable=True, comment="玩家7的手牌2")

    p81 = db.Column(db.Integer, nullable=True, comment="玩家8的手牌1")
    p82 = db.Column(db.Integer, nullable=True, comment="玩家8的手牌2")

    p91 = db.Column(db.Integer, nullable=True, comment="玩家9的手牌1")
    p92 = db.Column(db.Integer, nullable=True, comment="玩家9的手牌2")

    winners = db.Column(db.Integer, comment="赢家，每个bit位代表一位赢家")

    create_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")  # 服务类型

    # license = db.Column(db.Text, comment="授权码")  # 服务描述

    def to_json(self):
        return OrderedDict(
                uid = self.uid,
                common = self.time,
                asset = self.asset,
                agent = self.agent,
                beta = self.beta,
                info = self.info,
                # opr_time = self.opr_time,
                license = self.license,
            )

    @classmethod
    def create_and_return(cls, **data):
        # return
        card = cls(**data)
        with app.app_context():
            db.session.add(card)
        # return uid

class ModelResults(db.Model):
    __tablename__ = 'results'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer, primary_key=True, index=True)
    uid         = db.Column(db.Integer, comment="第几局")
    winners     = db.Column(db.Integer, comment="赢家，每个bit位代表一位赢家")
    ok          = db.Column(db.Boolean, default=True, comment="是否算对了")
    who         = db.Column(db.String(255), comment="谁计算的结果")
    paixing     = db.Column(db.String(255), comment="什么牌型获胜")
    # cards       = db.Column(db.String(255), comment="手牌")
    usetime     = db.Column(db.Float, comment="用时，单位:ms , 0 代表崩了")
    create_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")

    @classmethod
    def create_and_return(cls, **data):
        card = cls(**data)
        with app.app_context():
            db.session.add(card)

class ModelUtxos(db.Model):
    __tablename__ = 'utxos'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer, primary_key=True, index=True)

    who         = db.Column(db.String(16), comment="谁")
    to          = db.Column(db.String(16), comment="转给谁")
    amount      = db.Column(db.Integer,    comment="数量")

    room        = db.Column(db.String(16), comment="房间")
    game        = db.Column(db.String(16), comment="游戏")
    roundid     = db.Column(db.String(16), comment="轮")
    allin       = db.Column(db.Boolean,    comment="allin?", default=False)

    reason      = db.Column(db.String(512), comment="备注")
    create_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")

# 积分账户
class ModelCash(db.Model):
    __tablename__ = 'cash'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer,     primary_key=True, index=True)
    uid         = db.Column(db.String(16),  comment="身份uid", nullable=False)
    amount      = db.Column(db.BigInteger,  comment="余量", nullable=False)

    name        = db.Column(db.String(255), comment="姓名", nullable=True)
    detail      = db.Column(db.Text,        comment="备注", nullable=True)

    status      = db.Column(db.Boolean,     comment="记录有/失效", nullable=False, server_default=text('true'))
    removed     = db.Column(db.Boolean,     comment="删除标记",    nullable=False, server_default=text('false'))
    create_time = db.Column(db.DateTime,    comment="创建时间",    nullable=False, default=datetime.now)

    @classmethod
    def create_bank(cls):
        cash = ModelCash(
            uid="bank",
            name="银行",
            amount=10**8,
            detail="银行有一个亿",
            )
        db.session.add(cash)
        db.session.commit()

class ModelRoom(db.Model):
    __tablename__ = 'room'
    __table_args__ = {'extend_existing': True}
    # __table_args__ = (
    #         db.UniqueConstraint('uuid', 'types'),
    #     )

    id          = db.Column(db.Integer,     primary_key=True, index=True)
    # uid         = db.Column(db.String(16),  comment="房间id",  nullable=False, primary_key=True)
    bank        = db.Column(db.String(16),  comment="银行", nullable=True)
    dealer      = db.Column(db.String(16),  comment="荷官", nullable=True)
    judge       = db.Column(db.String(16),  comment="裁判", nullable=True)

    name        = db.Column(db.String(255), comment="别名", nullable=True)
    detail      = db.Column(db.Text,        comment="备注", nullable=True)

    # types       = db.Column(db.Integer, db.ForeignKey("types.id"), comment="账户类型", nullable=False, primary_key=True)

    status      = db.Column(db.String(16),  comment="状态",       nullable=True,  server_default='gaming')
    removed     = db.Column(db.Boolean,     comment="删除标记",    nullable=False, server_default=text('false'))
    create_time = db.Column(db.DateTime,    comment="创建时间",    nullable=False, default=datetime.now)

    def to_json(self):
        # strace()
        return {
            "id"           : self.id,
            "bank"         : self.bank,
            "dealer"       : self.dealer,
            "judge"        : self.judge,
            "name"         : self.name,
            "detail"       : self.detail,
            "status"       : self.status,
            "removed"      : self.removed,
            "create_time"  : self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
        }

class ModelRoomSeat(db.Model):
    __tablename__ = 'roomseat'
    __table_args__ = {'extend_existing': True}

    id          = db.Column(db.Integer,     primary_key=True, index=True)
    room        = db.Column(db.Integer,     comment="房间",    nullable=True)
    number      = db.Column(db.Integer,     comment="座号",    nullable=False, default=1)
    uid         = db.Column(db.String(16),  comment="玩家",    nullable=True)
    status      = db.Column(db.String(16),  comment="状态",    nullable=True)
    create_time = db.Column(db.DateTime,    comment="创建时间", nullable=False, default=datetime.now)

def flush():
    db.session.commit()
    db.session.remove()

@app.cli.command("db")
def run(*args, **kwargs):
    """在迁移过程中执行额外的 SQL 语句"""
    with app.app_context():
        # db.session.execute(text("""alter table users add  UNIQUE KEY id_UNIQUE (id) """))
        # db.session.execute(text("""alter table users modify column id int(11) NOT NULL AUTO_INCREMENT"""))
        # db.session.execute(text("""alter table users AUTO_INCREMENT=1000"""))
        ModelCash.create_bank()

app.cli.add_command(run, "up")
migrate = Migrate(app, db)

